#include<math.h>

#include "DH_key_init.h"

static unsigned int unused_fsm;

/* callbacks for FSM state change for the FSM events */
void sent_exponent_notify_CB(DH_PARAMS *dh_fsm);
void recv_exponent_notify_CB(DH_PARAMS *dh_fsm);
void exchange_notify_CB(DH_PARAMS *dh_fsm);


long compute_exponent(long base,long power)
{
  return pow(base,power);
  
}



void state_transition(DH_PARAMS *dh_fsm,DH_EVENTS event)
{
 switch(dh_fsm -> fsm_state) 
 {
   case INIT:
     if(event == SENT_EXPONENT_EV)
     {
       dh_fsm -> fsm_state = SENT_EXPONENT;
       dh_fsm -> sent_exponent = 1;
     }
     if(event == RECV_EXPONENT_EV)
     {
       dh_fsm -> fsm_state = RECV_EXPONENT;
       dh_fsm -> recv_exponent = 1;
     }
     
     break;
     
   case SENT_EXPONENT:
     if(event == RECV_EXPONENT_EV)
     {
       dh_fsm -> fsm_state = RECV_EXPONENT;
       dh_fsm -> recv_exponent = 1;
     }
     if(event == EXCHANGE_EV)
     {
      dh_fsm -> fsm_state = EXCHANGE_DONE;
      dh_fsm -> exchange = 1;
     }
     
     break;
   
   case RECV_EXPONENT:
     if(event == SENT_EXPONENT_EV)
     {
       dh_fsm -> fsm_state = SENT_EXPONENT;
       dh_fsm -> recv_exponent = 1;
     }
     if(event == EXCHANGE_EV)
     {
       dh_fsm -> fsm_state = EXCHANGE_DONE;
       dh_fsm -> exchange = 1;
     }  
     
     break;
     
   default :
     break;
   
 }
  
}



int init_DH_global_params(DH_PARAMS *dh_fsm)
{
  dh_fsm->fsm_id=unused_fsm++;
  dh_fsm->fsm_state=INIT;
  dh_fsm->sent_exponent=0;
  dh_fsm->recv_exponent=0;
  dh_fsm->exchange=0;
  dh_fsm->base=2;
  dh_fsm->sent_exponent_notify = sent_exponent_notify_CB;
  dh_fsm->recv_exponent_notify = recv_exponent_notify_CB;
  dh_fsm->exchange_notify = exchange_notify_CB;
  dh_fsm->state_table_transition = state_transition;
  
  return DH_SUCCESS;
  
}





init_DH_session(DH_PARAMS *dh_fsm, long exponent)
{
  
  int send_DH_packet(unsigned long exponent);
  
  int process_RX_packet(DH_PACKET *packet);
  
}




int init_DH_key_exchange(void)
{
  
  
  DH_PARAMS dh_fsm;
  long exponent;
  
  if(init_DH_global_params(&dh_fsm) != DH_SUCCESS)
    return DH_ERROR;
  
  exponent = compute_exponent(long dh_fsm.base,10);
  
  if(init_DH_session(&dh_fsm,exponent) != DH_SUCCESS)
    return DH_ERROR;
  
}

void sent_exponent_notify_CB(DH_PARAMS *dh_fsm)
{
  dh_fsm->state_table_transition(dh_fsm,SENT_EXPONENT_EV);  
}

void recv_exponent_notify_CB(DH_PARAMS *dh_fsm)
{
  dh_fsm->state_table_transition(dh_fsm,RECV_EXPONENT_EV);
}

void exchange_notify_CB(DH_PARAMS *dh_fsm)
{
  dh_fsm->state_table_transition(dh_fsm,EXCHANGE_EV);
}
